
`timescale 1 ps / 1 ps

module Soc_xlnx(
    ddr4_sdram_c1_083_act_n,
    ddr4_sdram_c1_083_adr,
    ddr4_sdram_c1_083_ba,
    ddr4_sdram_c1_083_bg,
    ddr4_sdram_c1_083_ck_c,
    ddr4_sdram_c1_083_ck_t,
    ddr4_sdram_c1_083_cke,
    ddr4_sdram_c1_083_cs_n,
    ddr4_sdram_c1_083_dm_n,
    ddr4_sdram_c1_083_dq,
    ddr4_sdram_c1_083_dqs_c,
    ddr4_sdram_c1_083_dqs_t,
    ddr4_sdram_c1_083_odt,
    ddr4_sdram_c1_083_reset_n,
    default_250mhz_clk1_clk_n,
    default_250mhz_clk1_clk_p,
    reset,
    rs232_uart_rxd,
    rs232_uart_txd
    );

output             ddr4_sdram_c1_083_act_n;
output    [16:0]   ddr4_sdram_c1_083_adr;
output    [1 :0]   ddr4_sdram_c1_083_ba;
output             ddr4_sdram_c1_083_bg;
output             ddr4_sdram_c1_083_ck_c;
output             ddr4_sdram_c1_083_ck_t;
output             ddr4_sdram_c1_083_cke;
output             ddr4_sdram_c1_083_cs_n;
inout     [7 :0]   ddr4_sdram_c1_083_dm_n;
inout     [63:0]   ddr4_sdram_c1_083_dq;
inout     [7 :0]   ddr4_sdram_c1_083_dqs_c;
inout     [7 :0]   ddr4_sdram_c1_083_dqs_t;
output             ddr4_sdram_c1_083_odt;
output             ddr4_sdram_c1_083_reset_n;
input              default_250mhz_clk1_clk_n;
input              default_250mhz_clk1_clk_p;
input              reset;
input              rs232_uart_rxd;
output             rs232_uart_txd;

// parameter
parameter int unsigned AXI_ID_WIDTH      = 8;
parameter int unsigned AXI_ADDR_WIDTH    = 48;
parameter int unsigned AXI_DATA_WIDTH    = 128;
parameter int unsigned AXI_USER_WIDTH    = 2;

// declaration wire

wire               clk_300M;
wire               clk_200M;
wire               clk_100M;
wire               clk_50M;
wire               clk_20M;
wire               clk_10M;
wire               bd_soc_clk;
wire               core_reset;
wire               core_reset_b;
wire               peripheral_aresetn;
wire               ddr4_sdram_c1_083_act_n;
wire   [16 :0]     ddr4_sdram_c1_083_adr;
wire   [1  :0]     ddr4_sdram_c1_083_ba;
wire               ddr4_sdram_c1_083_bg;
wire               ddr4_sdram_c1_083_ck_c;
wire               ddr4_sdram_c1_083_ck_t;
wire               ddr4_sdram_c1_083_cke;
wire               ddr4_sdram_c1_083_cs_n;
wire   [7  :0]     ddr4_sdram_c1_083_dm_n;
wire   [63 :0]     ddr4_sdram_c1_083_dq;
wire   [7  :0]     ddr4_sdram_c1_083_dqs_c;
wire   [7  :0]     ddr4_sdram_c1_083_dqs_t;
wire               ddr4_sdram_c1_083_odt;
wire               ddr4_sdram_c1_083_reset_n;
wire               default_250mhz_clk1_clk_n;
wire               default_250mhz_clk1_clk_p;
wire               reset;
wire               rs232_uart_rxd;
wire               rs232_uart_txd;

wire   [AXI_ADDR_WIDTH-1 :0]   s_axi_araddr;
wire   [1 :0]      s_axi_arburst;
wire   [3 :0]      s_axi_arcache;
wire   [AXI_ID_WIDTH-1 :0]     s_axi_arid;
wire   [7 :0]      s_axi_arlen;
wire   [0 :0]      s_axi_arlock;
wire   [2 :0]      s_axi_arprot;
wire   [3 :0]      s_axi_arqos;
wire               s_axi_arready;
wire   [3 :0]      s_axi_arregion;
wire   [2 :0]      s_axi_arsize;
wire               s_axi_arvalid;
wire   [AXI_ADDR_WIDTH-1 :0]   s_axi_awaddr;
wire   [1 :0]      s_axi_awburst;
wire   [3 :0]      s_axi_awcache;
wire   [AXI_ID_WIDTH-1:0]      s_axi_awid;
wire   [7 :0]      s_axi_awlen;
wire   [0 :0]      s_axi_awlock;
wire   [2 :0]      s_axi_awprot;
wire   [3 :0]      s_axi_awqos;
wire               s_axi_awready;
wire   [3 :0]      s_axi_awregion;
wire   [2 :0]      s_axi_awsize;
wire               s_axi_awvalid;
wire   [AXI_ID_WIDTH-1:0]      s_axi_bid;
wire               s_axi_bready;
wire   [1 :0]      s_axi_bresp;
wire               s_axi_bvalid;
wire   [AXI_DATA_WIDTH-1 :0]   s_axi_rdata;
wire   [AXI_ID_WIDTH-1:0]      s_axi_rid;
wire               s_axi_rlast;
wire               s_axi_rready;
wire   [1 :0]      s_axi_rresp;
wire               s_axi_rvalid;
wire   [AXI_ID_WIDTH-1:0]      s_axi_wid;
wire   [AXI_DATA_WIDTH-1:0]    s_axi_wdata;
wire               s_axi_wlast;
wire               s_axi_wready;
wire   [15 :0]     s_axi_wstrb;
wire               s_axi_wvalid;

wire               vio_cpu_reset;
wire               vio_system_reset;
wire               vio_ddr_reset;

wire   [1  :0]     core_in_core_id;
wire   [39 :0]     core_in_interrupt;
wire               core_in_ipi;
wire               uart_int;

wire               pll_cpu_clk;
wire               had_pad_jtg_tdo;      
wire               had_pad_jtg_tdo_en;  
wire               pad_cpu_rst_b;
wire   [1 :0]      biu_pad_lpmd_b;
wire               pad_had_jtg_tclk;
wire               pad_had_jtg_tdi;   
wire               pad_had_jtg_trst_b;
wire   [7 :0]      ext_interrupt;

assign core_reset_b       = ~core_reset;

assign  pad_had_jtg_tclk  = pll_cpu_clk;
assign  pad_cpu_rst_b     = core_reset_b;
assign  pad_had_jtg_tdi   = '0;
assign  ext_interrupt[7:0] = {6'b0, 1'b0, uart_int};

cpu_subsystem  cpu_subsystem (
  // AR
  .biu_pad_araddr        (s_axi_araddr       ),
  .biu_pad_arburst       (s_axi_arburst      ),
  .biu_pad_arcache       (s_axi_arcache      ),
  .biu_pad_arid          (s_axi_arid         ),
  .biu_pad_arlen         (s_axi_arlen        ),
  .biu_pad_arlock        (s_axi_arlock       ),
  .biu_pad_arprot        (s_axi_arprot       ),
  .biu_pad_arsize        (s_axi_arsize       ),
  .biu_pad_arvalid       (s_axi_arvalid      ),
  .pad_biu_arready       (s_axi_arready      ),
  
  // AW
  .biu_pad_awaddr        (s_axi_awaddr       ),
  .biu_pad_awburst       (s_axi_awburst      ),
  .biu_pad_awcache       (s_axi_awcache      ),
  .biu_pad_awid          (s_axi_awid         ),
  .biu_pad_awlen         (s_axi_awlen        ),
  .biu_pad_awlock        (s_axi_awlock       ),
  .biu_pad_awprot        (s_axi_awprot       ),
  .biu_pad_awsize        (s_axi_awsize       ),
  .biu_pad_awvalid       (s_axi_awvalid      ),
  .pad_biu_awready       (s_axi_awready      ),
  
  // W
  .biu_pad_wdata         (s_axi_wdata        ),
  .biu_pad_wid           (s_axi_wid          ),
  .biu_pad_wlast         (s_axi_wlast        ),
  .biu_pad_wstrb         (s_axi_wstrb        ),
  .biu_pad_wvalid        (s_axi_wvalid       ),
  .pad_biu_wready        (s_axi_wready       ),
  
  // B
  .biu_pad_bready        (s_axi_bready       ),
  .pad_biu_bid           (s_axi_bid          ),
  .pad_biu_bresp         (s_axi_bresp        ),
  .pad_biu_bvalid        (s_axi_bvalid       ),
  
  // R
  .biu_pad_rready        (s_axi_rready       ),
  .pad_biu_rdata         (s_axi_rdata        ),
  .pad_biu_rid           (s_axi_rid          ),
  .pad_biu_rlast         (s_axi_rlast        ),
  .pad_biu_rresp         ({2'b0,s_axi_rresp} ),
  .pad_biu_rvalid        (s_axi_rvalid       ),

  /// MISC
  .axim_clk_en           (1'b1               ),
  .biu_pad_lpmd_b        (biu_pad_lpmd_b     ),
  .had_pad_jtg_tdo       (                   ),
  .had_pad_jtg_tdo_en    (                   ),
  .i_pad_jtg_tms         (                   ),  /// No Input
  .pad_cpu_rst_b         (pad_cpu_rst_b      ),
  .pad_yy_dft_clk_rst_b  (pad_cpu_rst_b      ),
  .pad_had_jtg_tclk      (pad_had_jtg_tclk   ),
  .pad_had_jtg_tdi       ('0                 ),
  .pad_had_jtg_trst_b    (pad_cpu_rst_b      ),
  .pll_cpu_clk           (pll_cpu_clk        ),
  .ext_interrupt         (ext_interrupt      ),
  .xx_intc_vld           (core_in_interrupt  )
);

assign  s_axi_awqos = '0;
assign  s_axi_awregion = '0;

assign  s_axi_arqos = '0;
assign  s_axi_arregion = '0;

wire [47:0]        bd_axi_araddr;
wire [1:0]         bd_axi_arburst;
wire [3:0]         bd_axi_arcache;
wire [AXI_ID_WIDTH-1:0]      bd_axi_arid;
wire [7:0]         bd_axi_arlen;
wire [0:0]         bd_axi_arlock;
wire [2:0]         bd_axi_arprot;
wire [3:0]         bd_axi_arqos;
wire               bd_axi_arready;
wire [3:0]         bd_axi_arregion;
wire [2:0]         bd_axi_arsize;
wire               bd_axi_arvalid;
wire [47:0]        bd_axi_awaddr;
wire [1:0]         bd_axi_awburst;
wire [3:0]         bd_axi_awcache;
wire [AXI_ID_WIDTH-1:0]      bd_axi_awid;
wire [7:0]         bd_axi_awlen;
wire [0:0]         bd_axi_awlock;
wire [2:0]         bd_axi_awprot;
wire [3:0]         bd_axi_awqos;
wire               bd_axi_awready;
wire [3:0]         bd_axi_awregion;
wire [2:0]         bd_axi_awsize;
wire               bd_axi_awvalid;
wire [AXI_ID_WIDTH-1:0]      bd_axi_bid;
wire               bd_axi_bready;
wire [1:0]         bd_axi_bresp;
wire               bd_axi_bvalid;
wire [127:0]       bd_axi_rdata;
wire [AXI_ID_WIDTH-1:0]      bd_axi_rid;
wire               bd_axi_rlast;
wire               bd_axi_rready;
wire [1:0]         bd_axi_rresp;
wire               bd_axi_rvalid;
wire [127:0]       bd_axi_wdata;
wire               bd_axi_wlast;
wire               bd_axi_wready;
wire [15:0]        bd_axi_wstrb;
wire               bd_axi_wvalid;


// USE_XLNX_CC is that we use xilinx clock_converter for 50MHz->100MHz
`ifdef USE_XLNX_CC
xlnx_clock_converter clock_converter (
  .s_axi_aclk        (pll_cpu_clk),       
  .s_axi_aresetn     (peripheral_aresetn),
  .s_axi_awid        (s_axi_awid),
  .s_axi_awaddr      ({11'b0, s_axi_awaddr[36:0]}),
  .s_axi_awlen       (s_axi_awlen),
  .s_axi_awsize      (s_axi_awsize),
  .s_axi_awburst     (s_axi_awburst),
  .s_axi_awlock      (s_axi_awlock),
  .s_axi_awcache     (s_axi_awcache),
  .s_axi_awprot      (s_axi_awprot),
  .s_axi_awregion    (s_axi_awregion),
  .s_axi_awqos       (s_axi_awqos),
  .s_axi_awvalid     (s_axi_awvalid),
  .s_axi_awready     (s_axi_awready),
  .s_axi_wdata       (s_axi_wdata),
  .s_axi_wstrb       (s_axi_wstrb),
  .s_axi_wlast       (s_axi_wlast),
  .s_axi_wvalid      (s_axi_wvalid),
  .s_axi_wready      (s_axi_wready),
  .s_axi_bid         (s_axi_bid),
  .s_axi_bresp       (s_axi_bresp),
  .s_axi_bvalid      (s_axi_bvalid),
  .s_axi_bready      (s_axi_bready),
  .s_axi_arid        (s_axi_arid),
  .s_axi_araddr      ({11'b0, s_axi_araddr[36:0]}),
  .s_axi_arlen       (s_axi_arlen),
  .s_axi_arsize      (s_axi_arsize),
  .s_axi_arburst     (s_axi_arburst),
  .s_axi_arlock      (s_axi_arlock),
  .s_axi_arcache     (s_axi_arcache),
  .s_axi_arprot      (s_axi_arprot),
  .s_axi_arregion    (s_axi_arregion),
  .s_axi_arqos       (s_axi_arqos),
  .s_axi_arvalid     (s_axi_arvalid),
  .s_axi_arready     (s_axi_arready),
  .s_axi_rid         (s_axi_rid),
  .s_axi_rdata       (s_axi_rdata),
  .s_axi_rresp       (s_axi_rresp),
  .s_axi_rlast       (s_axi_rlast),
  .s_axi_rvalid      (s_axi_rvalid),
  .s_axi_rready      (s_axi_rready),
  
  .m_axi_aclk        (bd_soc_clk),        
  .m_axi_aresetn     (peripheral_aresetn),
  .m_axi_awid        (bd_axi_awid),
  .m_axi_awaddr      (bd_axi_awaddr),
  .m_axi_awlen       (bd_axi_awlen),
  .m_axi_awsize      (bd_axi_awsize),
  .m_axi_awburst     (bd_axi_awburst),
  .m_axi_awlock      (bd_axi_awlock),
  .m_axi_awcache     (bd_axi_awcache),
  .m_axi_awprot      (bd_axi_awprot),
  .m_axi_awregion    (bd_axi_awregion),
  .m_axi_awqos       (bd_axi_awqos),
  .m_axi_awvalid     (bd_axi_awvalid),
  .m_axi_awready     (bd_axi_awready),
  .m_axi_wdata       (bd_axi_wdata),
  .m_axi_wstrb       (bd_axi_wstrb),
  .m_axi_wlast       (bd_axi_wlast),
  .m_axi_wvalid      (bd_axi_wvalid),
  .m_axi_wready      (bd_axi_wready),
  .m_axi_bid         (bd_axi_bid),
  .m_axi_bresp       (bd_axi_bresp),
  .m_axi_bvalid      (bd_axi_bvalid),
  .m_axi_bready      (bd_axi_bready),
  .m_axi_arid        (bd_axi_arid),
  .m_axi_araddr      (bd_axi_araddr),
  .m_axi_arlen       (bd_axi_arlen),
  .m_axi_arsize      (bd_axi_arsize),
  .m_axi_arburst     (bd_axi_arburst),
  .m_axi_arlock      (bd_axi_arlock),
  .m_axi_arcache     (bd_axi_arcache),
  .m_axi_arprot      (bd_axi_arprot),
  .m_axi_arregion    (bd_axi_arregion),
  .m_axi_arqos       (bd_axi_arqos),
  .m_axi_arvalid     (bd_axi_arvalid),
  .m_axi_arready     (bd_axi_arready),
  .m_axi_rid         (bd_axi_rid),
  .m_axi_rdata       (bd_axi_rdata),
  .m_axi_rresp       (bd_axi_rresp),
  .m_axi_rlast       (bd_axi_rlast),
  .m_axi_rvalid      (bd_axi_rvalid),
  .m_axi_rready      (bd_axi_rready)
);

`else 
assign  bd_axi_arid[AXI_ID_WIDTH-1:0]   =   s_axi_arid[AXI_ID_WIDTH-1:0];
assign  bd_axi_araddr[47:0]   =   {11'b0, s_axi_araddr[36:0]};
assign  bd_axi_arlen[7:0]     =   s_axi_arlen[7:0];
assign  bd_axi_arsize[2:0]    =   s_axi_arsize[2:0];
assign  bd_axi_arburst[1:0]   =   s_axi_arburst[1:0];
assign  bd_axi_arlock[0:0]    =   s_axi_arlock[0:0];
assign  bd_axi_arcache[3:0]   =   s_axi_arcache[3:0];
assign  bd_axi_arprot[2:0]    =   s_axi_arprot[2:0];
assign  bd_axi_arregion[3:0]  =   s_axi_arregion[3:0];
assign  bd_axi_arqos[3:0]     =   s_axi_arqos[3:0];
assign  bd_axi_arvalid        =   s_axi_arvalid;
assign  bd_axi_arready        =   s_axi_arready;
assign  bd_axi_rid[AXI_ID_WIDTH-1:0]    =   s_axi_rid[AXI_ID_WIDTH-1:0];
assign  bd_axi_rdata[127:0]   =   s_axi_rdata[127:0];
assign  bd_axi_rresp[1:0]     =   s_axi_rresp[1:0];
assign  bd_axi_rlast          =   s_axi_rlast;
assign  bd_axi_rready         =   s_axi_rready;
assign  bd_axi_rvalid         =   s_axi_rvalid;
assign  bd_axi_awid[AXI_ID_WIDTH-1:0]   =   s_axi_awid[AXI_ID_WIDTH-1:0];
assign  bd_axi_awaddr[47:0]   =   {11'b0, s_axi_awaddr[36:0]};
assign  bd_axi_awlen[7:0]     =   s_axi_awlen[7:0];
assign  bd_axi_awsize[2:0]    =   s_axi_awsize[2:0];
assign  bd_axi_awburst[1:0]   =   s_axi_awburst[1:0];
assign  bd_axi_awlock[0:0]    =   s_axi_awlock[0:0];
assign  bd_axi_awcache[3:0]   =   s_axi_awcache[3:0];
assign  bd_axi_awprot[2:0]    =   s_axi_awprot[2:0];
assign  bd_axi_awregion[3:0]  =   s_axi_awregion[3:0];
assign  bd_axi_awqos[3:0]     =   s_axi_awqos[3:0];
assign  bd_axi_awvalid        =   s_axi_awvalid;
assign  bd_axi_awready        =   s_axi_awready;
assign  bd_axi_wdata[127:0]   =   s_axi_wdata[127:0];
assign  bd_axi_wstrb[15:0]    =   s_axi_wstrb[15:0];
assign  bd_axi_wlast          =   s_axi_wlast;
assign  bd_axi_wvalid         =   s_axi_wvalid;
assign  bd_axi_wready         =   s_axi_wready;
assign  bd_axi_bid[AXI_ID_WIDTH-1:0]    =   s_axi_bid[AXI_ID_WIDTH-1:0];
assign  bd_axi_bresp[1:0]     =   s_axi_bresp[1:0];
assign  bd_axi_bvalid         =   s_axi_bvalid;
assign  bd_axi_bready         =   s_axi_bready;
`endif


assign  pll_cpu_clk = clk_100M;
assign  bd_soc_clk  = clk_100M;

xlnx_bd_soc_mini_wrapper  bd_soc (
   .ddr4_sdram_c1_083_act_n      (ddr4_sdram_c1_083_act_n),
   .ddr4_sdram_c1_083_adr        (ddr4_sdram_c1_083_adr),
   .ddr4_sdram_c1_083_ba         (ddr4_sdram_c1_083_ba),
   .ddr4_sdram_c1_083_bg         (ddr4_sdram_c1_083_bg),
   .ddr4_sdram_c1_083_ck_c       (ddr4_sdram_c1_083_ck_c),
   .ddr4_sdram_c1_083_ck_t       (ddr4_sdram_c1_083_ck_t),
   .ddr4_sdram_c1_083_cke        (ddr4_sdram_c1_083_cke),
   .ddr4_sdram_c1_083_cs_n       (ddr4_sdram_c1_083_cs_n),
   .ddr4_sdram_c1_083_dm_n       (ddr4_sdram_c1_083_dm_n),
   .ddr4_sdram_c1_083_dq         (ddr4_sdram_c1_083_dq),
   .ddr4_sdram_c1_083_dqs_c      (ddr4_sdram_c1_083_dqs_c),
   .ddr4_sdram_c1_083_dqs_t      (ddr4_sdram_c1_083_dqs_t),
   .ddr4_sdram_c1_083_odt        (ddr4_sdram_c1_083_odt),
   .ddr4_sdram_c1_083_reset_n    (ddr4_sdram_c1_083_reset_n),
   .default_250mhz_clk1_clk_n    (default_250mhz_clk1_clk_n),
   .default_250mhz_clk1_clk_p    (default_250mhz_clk1_clk_p),
   
   .reset                        (reset),
   
   .rs232_uart_rxd               (rs232_uart_rxd),
   .rs232_uart_txd               (rs232_uart_txd),
   .uart_int                     (uart_int),
   
   .vio_cpu_reset                (vio_cpu_reset),

   // .clk_300M                     (clk_300M),
   .clk_100M                     (clk_100M),
   .clk_50M                      (clk_50M),
   .core_reset                   (core_reset),
   .peripheral_aresetn           (peripheral_aresetn),

   // AXI 
   .s_axi_araddr                 (bd_axi_araddr),
   .s_axi_arburst                (bd_axi_arburst),
   .s_axi_arcache                (bd_axi_arcache),
   .s_axi_arid                   (bd_axi_arid),
   .s_axi_arlen                  (bd_axi_arlen),
   .s_axi_arlock                 (bd_axi_arlock),
   .s_axi_arprot                 (bd_axi_arprot),
   .s_axi_arqos                  (bd_axi_arqos),
   .s_axi_arready                (bd_axi_arready),
   .s_axi_arsize                 (bd_axi_arsize),
   .s_axi_arvalid                (bd_axi_arvalid),
   .s_axi_awaddr                 (bd_axi_awaddr),
   .s_axi_awburst                (bd_axi_awburst),
   .s_axi_awcache                (bd_axi_awcache),
   .s_axi_awid                   (bd_axi_awid),
   .s_axi_awlen                  (bd_axi_awlen),
   .s_axi_awlock                 (bd_axi_awlock),
   .s_axi_awprot                 (bd_axi_awprot),
   .s_axi_awqos                  (bd_axi_awqos),
   .s_axi_awready                (bd_axi_awready),
   .s_axi_awsize                 (bd_axi_awsize),
   .s_axi_awvalid                (bd_axi_awvalid),
   .s_axi_bid                    (bd_axi_bid),
   .s_axi_bready                 (bd_axi_bready),
   .s_axi_bresp                  (bd_axi_bresp),
   .s_axi_bvalid                 (bd_axi_bvalid),
   .s_axi_rdata                  (bd_axi_rdata),
   .s_axi_rid                    (bd_axi_rid),
   .s_axi_rlast                  (bd_axi_rlast),
   .s_axi_rready                 (bd_axi_rready),
   .s_axi_rresp                  (bd_axi_rresp),
   .s_axi_rvalid                 (bd_axi_rvalid),
   .s_axi_wdata                  (bd_axi_wdata),
   .s_axi_wlast                  (bd_axi_wlast),
   .s_axi_wready                 (bd_axi_wready),
   .s_axi_wstrb                  (bd_axi_wstrb),
   .s_axi_wvalid                 (bd_axi_wvalid)
);

// for upload kernel to ddr memory.
xlnx_vio xlnx_vio(
   .clk                          (clk_100M),
   .probe_out0                   (vio_cpu_reset),
   .probe_out1                   (vio_system_reset),
   .probe_out2                   (vio_ddr_reset)
);

endmodule
